/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "加载保存属性.h"
#include "文件/文件.h"

#include <file_载入保存数据.h>
#include <file_文件名数据.h>
#include "core/动画/an_曲线.h"
#include "core/设备内存缓存.h"
#include "core/属性.h"

#include <zlib.h>



void f_prop_Load(S_Props& prop, FILE* f) {
	uint32 type = 0;
	//fread(&type, sizeof(uint32), 1, f);
	switch (prop.m_Type) {
		case E_值类型::e_Type_Bool:
			fread(prop.m_Value, sizeof(bool), 1, f);
			break;
		case E_值类型::e_Type_F32:
			fread(prop.m_Value, sizeof(float32), 1, f);
			break;
		case E_值类型::e_Type_I32:
			fread(prop.m_Value, sizeof(int32), 1, f);
			break;
		case E_值类型::e_Type_UI32:
			fread(prop.m_Value, sizeof(uint32), 1, f);
			break;
		case E_值类型::e_Type_Enum:
			fread(&f_prop_enum(prop), sizeof(int32), 1, f);
			break;
		case E_值类型::e_Type_Vec2:
			fread(prop.m_Value, sizeof(vec2), 1, f);
			break;
		case E_值类型::e_Type_Vec3:
			fread(prop.m_Value, sizeof(vec3), 1, f);
			break;
		case E_值类型::e_Type_iVec2:
			fread(prop.m_Value, sizeof(ivec2), 1, f);
			break;
		case E_值类型::e_Type_uVec2:
			fread(prop.m_Value, sizeof(uvec2), 1, f);
			break;
		case E_值类型::e_Type_路径:
			f_prop_Path(prop) = f_读取字符串(f);
			break;
		case E_值类型::e_Type_Str:
			f_prop_Str(prop) = f_file_读取字符串(f);
			break;
		case E_值类型::e_Type_LineText:
			f_prop_LineStr(prop) = f_file_读取字符串(f);
			break;
		case E_值类型::e_Type_2D曲线:
			 f_an_Load(f_prop_2DCurve(prop), f);
			break;
		case E_值类型::e_Type_Bool_1D: {
			auto item = f_prop_Bool_1D(prop);
			fread(&prop.m_值元素个数, sizeof(uint8), 1, f);
			for (uint32 i = 0; i < prop.m_值元素个数; ++i) {
				fread(&item->m_Value, sizeof(uint8), 1, f);
			}
			break;
		}
		case E_值类型::e_Type_MapPtr_Array1D: {
			S_MapPtr& e = f_prop_MapPrt(prop);
			fread(&e.m_当前项, sizeof(uint64), 1, f);
			break;
		}
		case E_值类型::e_Type_Object_1D:
			break;
		default:
			break;
	}
}

void f_prop_Save(S_Props& prop, FILE* f) {
	uint32 type = prop.m_Type;
	
	switch (prop.m_Type) {
		case E_值类型::e_Type_Bool:
			fwrite(prop.m_Value, sizeof(bool), 1, f);
			break;
		case E_值类型::e_Type_F32:
			fwrite(prop.m_Value, sizeof(float32), 1, f);
			break;
		case E_值类型::e_Type_I32:
			fwrite(prop.m_Value, sizeof(int32), 1, f);
			break;
		case E_值类型::e_Type_UI32:
			fwrite(prop.m_Value, sizeof(uint32), 1, f);
			break;
		case E_值类型::e_Type_Enum:
			fwrite(&f_prop_enum(prop), sizeof(int32), 1, f);
			break;
		case E_值类型::e_Type_Vec2:
			fwrite(prop.m_Value, sizeof(vec2), 1, f);
			break;
		case E_值类型::e_Type_Vec3:
			fwrite(prop.m_Value, sizeof(vec3), 1, f);
			break;
		case E_值类型::e_Type_iVec2:
			fwrite(prop.m_Value, sizeof(ivec2), 1, f);
			break;
		case E_值类型::e_Type_uVec2:
			fwrite(prop.m_Value, sizeof(uvec2), 1, f);
			break;
		case E_值类型::e_Type_Bounding:
			fwrite(prop.m_Value, sizeof(S_Cube), 1, f);
			break;
		case E_值类型::e_Type_路径:
			f_file_保存字符串(f, f_prop_Path(prop).string());
			break;
		case E_值类型::e_Type_Str:
			f_file_保存字符串(f, f_prop_Str(prop));
			break;
		case E_值类型::e_Type_LineText:
			f_file_保存字符串(f, f_prop_LineStr(prop));
			break;
		case E_值类型::e_Type_2D曲线:
			f_an_Save(f_prop_2DCurve(prop), f);
			break;
		case E_值类型::e_Type_Bool_1D: {
			auto item = f_prop_Bool_1D(prop);
			fwrite(&prop.m_值元素个数, sizeof(uint8), 1, f);
			for (uint32 i = 0; i < prop.m_值元素个数; ++i) {
				fwrite(&item->m_Value, sizeof(uint8), 1, f);
			}
			break;
		}
		case E_值类型::e_Type_MapPtr_Array1D: {
			S_MapPtr& e = f_prop_MapPrt(prop);
			fwrite(&e.m_当前项, sizeof(uint64), 1, f);
			break;
		}
		case E_值类型::e_Type_Object_1D:
			break;
		default:
			break;
	}
}





Inline static const uint8* f_加载容器属性对象(S_PropContainer& ContainerOut, const uint8* 块) {
	uint32 num = *((uint32*)块);
	块 = &(块[sizeof(uint32)]);

	ContainerOut.m_Item.resize(num);
	for (uint32 i = 0; i < num; ++i) {
		E_值类型 值类型 = E_值类型(*((uint64*)块));
		块 = &(块[sizeof(uint64)]);

		switch (值类型) {
			case E_值类型::e_Type_F32: {
				ContainerOut.m_Item[i] = f_alloc_F32Prop(nullptr, u"F32容器元素");
				break;
			}
			case E_值类型::e_Type_I8: {
				ContainerOut.m_Item[i] = f_alloc_I8Prop(nullptr, u"I8容器元素");
				break;
			}
			case E_值类型::e_Type_I32: {
				ContainerOut.m_Item[i] = f_alloc_I32Prop(nullptr, u"I32容器元素");
				break;
			}
			case E_值类型::e_Type_UI32: {
				ContainerOut.m_Item[i] = f_alloc_UI32Prop(nullptr, u"UI32容器元素", 0);
				break;
			}
			case E_值类型::e_Type_Bounding: {
				ContainerOut.m_Item[i] = f_alloc_BoundProp(nullptr, u"包围盒容器元素");
				break;
			}
			case E_值类型::e_Type_Vec2: {
				ContainerOut.m_Item[i] = f_alloc_Vec2Prop(nullptr, u"Vec2容器元素");
				break;
			}
			case E_值类型::e_Type_Vec3: {
				ContainerOut.m_Item[i] = f_alloc_Vec3Prop(nullptr, u"Vec2容器元素");
				break;
			}
			case E_值类型::e_Type_Vec4: {
				ContainerOut.m_Item[i] = f_alloc_Vec4Prop(nullptr, u"Vec2容器元素");
				break;
			}
			default:
				break;
		}
		块 = f_prop_Load(ContainerOut.m_Item[i], 块);
	}
	return 块;
}

const uint8* f_prop_Load(S_Props& prop, const uint8* 块) {
	uint32 type = 0;
	
	switch (prop.m_Type) {
		case E_值类型::e_Type_Bool:
			*((bool*)prop.m_Value) = *((bool*)块);
			return &块[1];
		case E_值类型::e_Type_I8:
			*((int8*)prop.m_Value) = *((int8*)块);
			return &块[1];
		case E_值类型::e_Type_F32:
			*((float32*)prop.m_Value) = *((float32*)块);
			return &块[sizeof(float32)];
		case E_值类型::e_Type_I32:
			*((int32*)prop.m_Value) = *((int32*)块);
			return &块[sizeof(int32)];

		case E_值类型::e_Type_UI32_FlagBits:
		case E_值类型::e_Type_UI32:
			*((uint32*)prop.m_Value) = *((uint32*)块);
			return &块[sizeof(uint32)];

		case E_值类型::e_Type_Enum:
			f_prop_enum(prop) = *((int32*)块);
			return &块[sizeof(int32)];
		case E_值类型::e_Type_Vec2:
			*((vec2*)prop.m_Value) = *((vec2*)块);
			return &块[sizeof(vec2)];
		case E_值类型::e_Type_Vec3:
			*((vec3*)prop.m_Value) = *((vec3*)块);
			return &块[sizeof(vec3)];
		case E_值类型::e_Type_iVec2:
			*((ivec2*)prop.m_Value) = *((ivec2*)块);
			return &块[sizeof(ivec2)];
		case E_值类型::e_Type_iVec3:
			*((ivec3*)prop.m_Value) = *((ivec3*)块);
			return &块[sizeof(ivec3)];
		case E_值类型::e_Type_uVec2:
			*((uvec2*)prop.m_Value) = *((uvec2*)块);
			return &块[sizeof(uvec2)];
		case E_值类型::e_Type_Bounding:
			*((S_Cube*)prop.m_Value) = *((S_Cube*)块);
			return &块[sizeof(S_Cube)];
		case E_值类型::e_Type_路径: {
			std::string str;
			const uint8* p = f_解字符串(str, 块);
			f_prop_Path(prop) = str;
			return p;
		}

		case E_值类型::e_Type_Str:
		
			return f_解宽字符串(f_prop_Str(prop), 块);
		case E_值类型::e_Type_LineText:
			return f_解宽字符串(f_prop_LineStr(prop), 块);
			
		case E_值类型::e_Type_ObjectContainerMap: {
			return f_解宽字符串(f_prop_ObjectMapKey(prop), 块);
		}

		case E_值类型::e_Type_2D曲线:
			return f_an_解(f_prop_2DCurve(prop), 块);
			
		case E_值类型::e_Type_Bool_1D: {
			auto item = f_prop_Bool_1D(prop);

			prop.m_值元素个数 = *((uint8*)块);
			块 = &块[1];

			S_PropVecBool* 元素开关 = f_prop_Bool_1D(prop);
			for (uint32 i = 0; i < prop.m_值元素个数; ++i) {
				
				元素开关[i].m_Value = 块[i];
				//memcpy(&item->m_Value, &块, prop.m_值元素个数);
			}
			return &块[prop.m_值元素个数];
		}
		case E_值类型::e_Type_MapPtr_Array1D: {
			S_MapPtr& e = f_prop_MapPrt(prop);
			e.m_当前项 = *((uint64*)块);
			return &块[sizeof(uint64)];
		}

		//case E_值类型::e_Type_UI8位域枚举: {
		//	f_prop_U8位域(prop) = *((uint8*)块);
		//	return &块[sizeof(uint8)];
		//}
		case E_值类型::e_Type_UI32位域枚举: {
			f_prop_UI32位域枚举(prop) = *((uint32*)块);
			return &块[sizeof(uint32)];
		}
		case E_值类型::e_Type_Object_1D:
			break;

		case E_值类型::e_Type_TexProp: {
			f_prop_TexProp(prop) = *((S_TextueProp*)块);
			return &块[sizeof(S_TextueProp)];
			break;
		}

		

		case E_值类型::e_Type_ContainerBool:
		case E_值类型::e_Type_ContainerF32:
		case E_值类型::e_Type_ContainerI8:
		case E_值类型::e_Type_ContainerI32:
		case E_值类型::e_Type_ContainerUI32:
		case E_值类型::e_Type_ContainerVec2:
		case E_值类型::e_Type_ContainerVec3:
		case E_值类型::e_Type_ContainerVec4:
		case E_值类型::e_Type_ContaineriVec2:
		case E_值类型::e_Type_ContaineriVec3:
		case E_值类型::e_Type_ContaineriVec4:
		case E_值类型::e_Type_ContainerBound:
		case E_值类型::e_Type_ContainerValue: {
			auto& ContainerOut = f_prop_Container(prop);
			return f_加载容器属性对象(ContainerOut, 块);
			break;
		}
		default:
			return &块[1];
	}
	return nullptr;
}

void f_prop_Save(S_Props& prop, S_UI8Array* 块) {
	uint32 type = prop.m_Type;

	switch (prop.m_Type) {
		case E_值类型::e_Type_Bool:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(bool));
			break;
		case E_值类型::e_Type_I8:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(int8));
			break;
		case E_值类型::e_Type_F32:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(float32));
			break;
		case E_值类型::e_Type_I32:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(int32));
			break;

		case E_值类型::e_Type_UI32_FlagBits:
		case E_值类型::e_Type_UI32:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(uint32));
			break;
		case E_值类型::e_Type_Enum:
			f_core_array_push_back_block((S_Array*)块, (uint8*)&f_prop_enum(prop), sizeof(int32));
			break;
		case E_值类型::e_Type_Vec2:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(vec2));
			break;
		case E_值类型::e_Type_Vec3:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(vec3));
			break;
		case E_值类型::e_Type_iVec2:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(ivec2));
			break;
		case E_值类型::e_Type_iVec3:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(ivec3));
			break;
		case E_值类型::e_Type_uVec2:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(uvec2));
			break;
		case E_值类型::e_Type_Bounding:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, sizeof(S_Cube));
			break;
		case E_值类型::e_Type_路径:
			f_包字符串(块, f_prop_Path(prop).string());
			break;

		case E_值类型::e_Type_Str:
			f_包宽字符串(块, f_prop_Str(prop));
			break;
		case E_值类型::e_Type_LineText:
			f_包宽字符串(块, f_prop_LineStr(prop));
			break;
		case E_值类型::e_Type_ObjectContainerMap: {
			f_包宽字符串(块, f_prop_ObjectMapKey(prop));
			break;
		}

		case E_值类型::e_Type_2D曲线:
			f_an_包(f_prop_2DCurve(prop), 块);
			break;
		case E_值类型::e_Type_Bool_1D: {
			auto item = f_prop_Bool_1D(prop);

			f_core_array_push_back_block((S_Array*)块, (uint8*)&prop.m_值元素个数, sizeof(uint8));
			S_PropVecBool* 元素开关 = f_prop_Bool_1D(prop);
			for (uint32 i = 0; i < prop.m_值元素个数; ++i) {
				f_core_array_push_back_block((S_Array*)块, (uint8*)&(元素开关[i].m_Value), sizeof(uint8));
			}
			break;
		}
		case E_值类型::e_Type_MapPtr_Array1D: {
			S_MapPtr& e = f_prop_MapPrt(prop);
			f_core_array_push_back_block((S_Array*)块, (uint8*)&e.m_当前项, sizeof(uint64));
			break;
		}

		case E_值类型::e_Type_UI8位域枚举: {
			uint32 e = f_prop_U8位域(prop);
			f_core_array_push_back_block((S_Array*)块, (uint8*)&e, sizeof(uint8));
			break;
		}
		case E_值类型::e_Type_UI32位域枚举: {
			uint32 e = f_prop_UI32位域枚举(prop);
			f_core_array_push_back_block((S_Array*)块, (uint8*)&e, sizeof(uint32));
			break;
		}
		case E_值类型::e_Type_Object_1D:
			break;

		case E_值类型::e_Type_TexProp: {
			auto e = f_prop_TexProp(prop);
			f_core_array_push_back_block((S_Array*)块, (uint8*)&e, sizeof(S_TextueProp));
			break;
		}


		case E_值类型::e_Type_ContainerBool:
		case E_值类型::e_Type_ContainerF32:
		case E_值类型::e_Type_ContainerI8:
		case E_值类型::e_Type_ContainerI32:
		case E_值类型::e_Type_ContainerUI32:
		case E_值类型::e_Type_ContainerVec2:
		case E_值类型::e_Type_ContainerVec3:
		case E_值类型::e_Type_ContainerVec4:
		case E_值类型::e_Type_ContaineriVec2:
		case E_值类型::e_Type_ContaineriVec3:
		case E_值类型::e_Type_ContaineriVec4:
		case E_值类型::e_Type_ContainerBound:
		case E_值类型::e_Type_ContainerValue: {
			auto& ContainerOut = f_prop_Container(prop);
			uint32 num = ContainerOut.m_Item.size();
			f_core_array_push_back_block((S_Array*)块, (uint8*)&num, sizeof(uint32));
			for (uint32 i = 0; i < num; ++i) {
				auto value_item = ContainerOut.m_Item[i];

				f_core_array_push_back_block((S_Array*)块, (uint8*)&(value_item.m_Type), sizeof(uint64));
				f_prop_Save(value_item, 块);
			}
			break;
		}

		default:
			f_core_array_push_back_block((S_Array*)块, (uint8*)prop.m_Value, 1);
			break;
	}
}

const uint8* f_prop_Load2(S_Props& prop, const uint8* 块) {
	uint64 type = *((uint64*)块);
	块 = &块[sizeof(uint64)];

	switch (type) {
		case E_值类型::e_Type_Enum: {
			prop = f_alloc_EnumProp(nullptr, {}, u"");
			break;
		}
		case E_值类型::e_Type_Bool: {
			prop = f_alloc_BoolProp(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_F32: {
			prop = f_alloc_F32Prop(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_I32: {
			prop = f_alloc_I32Prop(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_UI32: {
			prop = f_alloc_UI32Prop(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_Vec2: {
			prop = f_alloc_Vec2Prop(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_Vec3: {
			prop = f_alloc_Vec3Prop(nullptr, u"");
			break;
		}
		case E_值类型::e_Type_Vec4: {
			prop = f_alloc_Vec4Prop(nullptr, u"");
			break;
		}
	}

	return f_prop_Load(prop, 块);
}

void f_prop_Save2(S_Props& prop, S_UI8Array* 块) {
	uint64 type = prop.m_Type;
	f_core_array_push_back_block((S_Array*)块, (uint8*)&type, sizeof(uint64));

	f_prop_Save(prop, 块);
}

void f_file_补充路径后缀(S_Props& prop, S_Props& 后缀枚举) {
	auto& path = f_prop_LineStr(prop);
	path = f_file_补充文件路径后缀(path, u"." + f_prop_enumName(后缀枚举));
}





void f_文件块_写缓存数据块(FILE* F, const S_GPU内存块& 数据, bool 是否压缩) {
	uint32 数量 = 数据.m_Mem.m_数量;
	fwrite(&数量, sizeof(uint32), 1, F);

	if (!数量) return;

	uint32 元素大小 = 数据.m_Buf->m_Offset;

	fwrite(&元素大小, sizeof(uint32), 1, F);
	fwrite(&是否压缩, sizeof(bool), 1, F);

	if (是否压缩) {
		uLongf 压缩后大小 = 0;
		std::vector<uint8> 压缩点(数量 * 元素大小);

		compress((uint8*)压缩点.data(), &压缩后大小, (uint8*)f_bm_Address(数据), 压缩后大小);

		uint64 应对ZLIB这种纯类型 = 压缩后大小;
		fwrite(&应对ZLIB这种纯类型, sizeof(uint64), 1, F);
		fwrite((uint8*)压缩点.data(), sizeof(uint8), 压缩后大小, F);
	}
	else {
		fwrite(f_bm_Address(数据), 元素大小, 数量, F);
	}
}

void f_文件块_读缓存数据块(FILE* F, S_GPU内存块& 数据, bool) {
	uint32 数量 = 0;
	fread(&数量, sizeof(uint32), 1, F);

	if(!数量) return;
	uint32 元素大小 = 0;
	bool 是否压缩 = false;

	fread(&元素大小, sizeof(uint32), 1, F);
	fread(&是否压缩, sizeof(bool), 1, F);

	f_bm_resize(数据, 数量);

	if (是否压缩) {
		uint64 压缩后大小 = 0;
		fread(&压缩后大小, sizeof(uint64), 1, F);
		std::vector<uint8> 压缩点(压缩后大小);

		fread(压缩点.data(), sizeof(uint8), 压缩后大小, F);

		uLongf 压缩后大小_愚蠢类型 = 压缩后大小;
		uLongf 压缩前大小_愚蠢类型 = 压缩后大小;


		uncompress((uint8*)f_bm_Address(数据), &压缩前大小_愚蠢类型, 压缩点.data(), 数量 * 元素大小);
	}
	else {
		fread(f_bm_Address(数据), 元素大小, 数量, F);
	}
}




